home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Natural Order / Natural Order.c < prev    next >
C/C++ Source or Header  |  1996-06-21  |  3KB  |  76 lines

  1. // Natural Order
  2. // ©1996 Stuart Cheshire <cheshire@CS.Stanford.EDU>
  3. //
  4. // Natural Order patches IUMagString to make it sort strings containing numbers in a sensible order
  5. // See Natural Order ReadMe for more details
  6. // See TextUtils.h for the declaration of IUMagString etc.
  7.  
  8. #include <Traps.h>
  9. #include "StuTypes.h"
  10.  
  11. void main(void);
  12. pascal short my_pack6(const u_char *aPtr, const u_char *bPtr, short aLen, short bLen, short TrapSelector);
  13. pascal short sys_pack6(const u_char *aPtr, const u_char *bPtr, short aLen, short bLen, short TrapSelector);
  14. local pascal short StuMagString(const u_char *aPtr, const u_char *bPtr, short aLen, short bLen, short TrapSelector);
  15. #define SysMagString(A,B,C,D) sys_pack6((A),(B),(C),(D),0x000A)
  16.  
  17. local void entry_point(void)    /* no stack frame please ! */
  18.     {
  19.     asm    {    
  20.     @0                    move.l    a0, -(sp)
  21.                         DetachResource
  22.                         bra        main
  23.  
  24.     extern my_pack6:    cmp.w    #0x000A, 4(sp)
  25.                         beq        StuMagString
  26.     extern sys_pack6:    jmp        0x12345678
  27.         }
  28.     }
  29.  
  30. #define isdigit(X) ((X) >= '0' && (X) <= '9')
  31.  
  32. local pascal short StuMagString(const u_char *aPtr, const u_char *bPtr, short aLen, short bLen, short TrapSelector)
  33.     {
  34.     short result;
  35.     const u_char *a = aPtr, *aEnd = a + aLen;
  36.     const u_char *b = bPtr, *bEnd = b + bLen;
  37.     while (aPtr < aEnd && bPtr < bEnd)
  38.         {
  39.         while (a < aEnd && b < bEnd && !(isdigit(*a) && isdigit(*b))) { a++; b++; }
  40.         result = SysMagString(aPtr, bPtr, a-aPtr, b-bPtr);
  41.         if (result) return (result);
  42.         aPtr = a;
  43.         bPtr = b;
  44.         while (a < aEnd && b < bEnd && isdigit(*a) && isdigit(*b)) { a++; b++; }
  45.         if (a < aEnd && isdigit(*a)) return(1);
  46.         if (b < bEnd && isdigit(*b)) return(-1);
  47.         }
  48.     return(SysMagString(aPtr, bPtr, a-aPtr, b-bPtr));
  49.     }
  50.  
  51. local Boolean TrapAvailable(u_long trap)
  52.     {
  53.     TrapType tType = (trap & 0x800 ? ToolTrap : OSTrap);
  54.     if (trap & 0x800)                // if it is a ToolBox Trap
  55.         {
  56.         u_long n = 0x400;    // number of toolbox traps
  57.         if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  58.             n = 0x200;
  59.         if ((trap &= 0x7FF) >= n) trap = _Unimplemented;
  60.         }
  61.     return(NGetTrapAddress(trap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap));
  62.     }
  63.  
  64. typedef struct { WORD jmp; ProcPtr addr; } jmp;
  65. #define TBpatch(VEC,T,NEW) p=&((jmp*)VEC)->addr; \
  66.     *p = GetToolTrapAddress(T); SetToolTrapAddress((ProcPtr)NEW,T)
  67. #define OSpatch(VEC,T,NEW) p=&((jmp*)VEC)->addr; \
  68.     *p = GetOSTrapAddress(T); SetOSTrapAddress((ProcPtr)NEW,T)
  69.  
  70. export void main(void)
  71.     {
  72.     register ProcPtr *p;
  73.     TBpatch(sys_pack6, _Pack6, my_pack6);
  74.     if (TrapAvailable(_HWPriv)) FlushInstructionCache();
  75.     }
  76.